package video

import (
	"context"
	"gitee.com/bobo-rs/creative-framework/pkg/utils"
	"gitee.com/bobo-rs/innovideo-services/enums"
	"gitee.com/bobo-rs/innovideo-services/framework/dao"
	"gitee.com/bobo-rs/innovideo-services/framework/model"
	"gitee.com/bobo-rs/innovideo-services/framework/service"
	"gitee.com/bobo-rs/innovideo-services/library/exception"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/frame/g"
)

// SaveVideoEpisodes 保存视频续集数据
func (v *sVideo) SaveVideoEpisodes(ctx context.Context, item model.VideoEpisodesSaveItem) error {
	// 格式化视频清晰度
	if len(item.ResolutionList) > 0 {
		item.ResolutionSet = gjson.MustEncodeString(
			utils.NewArray(item.ResolutionList).Strings(dao.VideoResolution.Columns().Resolution),
		)
	}
	// 视频续集海报地址
	if item.AttachId != "" {
		item.ImageUrl = service.Attachment().MustAttachUrlByAttachId(ctx, item.AttachId)
	}

	// 保存数据
	return dao.VideoEpisodes.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		r, err := dao.VideoEpisodes.Ctx(ctx).OmitEmpty().Save(item.VideoEpisodes)
		if err != nil {
			return exception.New(`上传视频续集失败`)
		}
		// 视频续集ID
		episodesId, _ := r.LastInsertId()
		// 保存视频清晰度
		if len(item.ResolutionList) > 0 {
			err = v.SaveVideoResolution(ctx, uint(episodesId), item.ResolutionList...)
		}
		return err
	})
}

// GetEpisodesList 获取视频续集列表数据
func (v *sVideo) GetEpisodesList(ctx context.Context, in model.VideoEpisodesListInput) (out *model.VideoEpisodesListOutput, err error) {
	out = &model.VideoEpisodesListOutput{}
	// 获取数据列表
	err = dao.VideoEpisodes.Ctx(ctx).
		Where(dao.VideoEpisodes.Columns().VideoId, in.VideoId).
		OrderAsc(dao.VideoEpisodes.Columns().EpisodesNum).
		Scan(&out.Rows)
	if err != nil {
		return nil, exception.New(`暂无视频剧集`)
	}

	// 数据为空
	if len(out.Rows) == 0 {
		return nil, exception.New(`暂无视频剧集`)
	}

	out.Total = len(out.Rows)

	// 用户业务端不能直接获取视频播放地址-视频安全着想
	if in.FormSide == enums.FormSideBus {
		return
	}

	// 获取视频清晰度
	resolesMap, err := v.GetResolutionMapByEpisodesId(
		ctx, utils.NewArray(out.Rows).Units(dao.VideoEpisodes.Columns().Id)...,
	)
	if err != nil {
		return nil, err
	}
	// 迭代组装清晰度
	for key, item := range out.Rows {
		if resolutions, ok := resolesMap[item.Id]; ok {
			out.Rows[key].ResolutionList = resolutions
		}
	}

	return
}

// GetEpisodesDetail 获取视频续集详情
func (v sVideo) GetEpisodesDetail(ctx context.Context, episodesId uint) (detail *model.VideoEpisodesDetailItem, err error) {
	detail = &model.VideoEpisodesDetailItem{}
	// 获取详情
	err = v.EpisodesModel().DetailPri(ctx, episodesId, &detail)
	if err != nil {
		return nil, exception.New(`视频续集信息不存在`)
	}

	// 获取清晰度
	if resolesMap, _ := v.GetResolutionMapByEpisodesId(ctx, episodesId); resolesMap != nil {
		detail.ResolutionList = resolesMap[episodesId]
	}
	return
}

// GetEpisodesIdSetByVideoId 通过视频ID获取视频续集ID集合
func (v *sVideo) GetEpisodesIdSetByVideoId(ctx context.Context, videoId uint) ([]uint, error) {
	var ids []model.VideoEpisodesId
	// 获取视频续集ID列表
	err := v.EpisodesModel().Scan(ctx, g.Map{
		dao.VideoEpisodes.Columns().VideoId: videoId,
	}, &ids)
	if err != nil {
		return nil, err
	}
	// 获取续集ID
	return utils.NewArray(ids).Units(dao.VideoEpisodes.Columns().Id), nil
}

// MustGetEpisodesIdSetByVideoId 通过视频ID获取视频续集ID集合
func (v *sVideo) MustGetEpisodesIdSetByVideoId(ctx context.Context, videoId uint) []uint {
	ids, _ := v.GetEpisodesIdSetByVideoId(ctx, videoId)
	return ids
}

// GetEpisodesBuyList 获取待购买的剧集列表
func (v *sVideo) GetEpisodesBuyList(ctx context.Context, videoId uint, idSet []uint) (list []model.VideoEpisodesBuyItem, err error) {
	// 获取数据列表
	where := g.Map{
		dao.VideoEpisodes.Columns().VideoId: videoId,
	}
	if len(idSet) > 0 {
		where[dao.VideoEpisodes.Columns().Id] = idSet
	}
	err = v.EpisodesModel().Scan(ctx, where, &list)
	return
}

// GetRemainderNotBuyList 获取剩余未购买的剧集列表
func (v *sVideo) GetRemainderNotBuyList(ctx context.Context, episodesIdSet []uint) (list []model.VideoEpisodesBuyItem, err error) {
	if len(episodesIdSet) == 0 {
		return nil, exception.New(`缺少已购买的剧集ID`)
	}
	// 获取数据列表
	err = dao.VideoEpisodes.Ctx(ctx).
		WhereNot(dao.VideoEpisodes.Columns().Id, episodesIdSet).
		Scan(&list)
	return
}

// GetVideoEpisodesIds 获取视频剧集ID，适用于（获取免费剧集ID）
func (v *sVideo) GetVideoEpisodesIds(ctx context.Context, videoId uint, size int) (map[uint]bool, error) {
	var idSet []model.VideoEpisodesId
	err := dao.VideoEpisodes.Ctx(ctx).
		Where(dao.VideoEpisodes.Columns().VideoId, videoId).
		Limit(size).
		OrderAsc(dao.VideoEpisodes.Columns().EpisodesNum).
		Scan(&idSet)
	if err != nil {
		return nil, err
	}
	freeEpisodesMap := make(map[uint]bool)
	for _, item := range idSet {
		freeEpisodesMap[item.Id] = true
	}
	return freeEpisodesMap, nil
}

// deleteEpisodesByVideoId 处理通过视频ID删除视频续集
func (v *sVideo) deleteEpisodesByVideoId(ctx context.Context, videoId uint) error {
	ids := v.MustGetEpisodesIdSetByVideoId(ctx, videoId)
	if len(ids) == 0 {
		return nil
	}
	// 删除视频续集
	err := v.EpisodesModel().Delete(ctx, g.Map{
		dao.VideoEpisodes.Columns().VideoId: videoId,
	})
	if err != nil {
		return err
	}
	// 视频续集清晰度
	return v.ResolutionModel().Delete(ctx, g.Map{
		dao.VideoResolution.Columns().EpisodesId: ids,
	})
}
